from google.appengine.ext import db
from app.helpers.simplify import simplify
import md5

class Tag(db.Model):
  """ A tag is something we can filter ValueSets on """
  # For easier filtering
  dataset_key = db.Property()
  
  # Identity fields
  fieldset_key = db.Property()
  property_name = db.StringProperty()
  simplified_value = db.StringProperty()
  
  # How to display this tag to end user
  verbose_property = db.StringProperty()
  verbose_value = db.StringProperty()
  
  # How many entities with this tag?
  count = db.IntegerProperty(default=0)
  
  @classmethod
  def get_key_name(cls, fieldset_key, property_name, value):
    if hasattr(fieldset_key, 'key') and callable(fieldset_key.key):
      fieldset_key = fieldset_key.key()
    key_name = '-'.join((str(fieldset_key), property_name, str(simplify(value))))
    return 'k' + md5.new(key_name).hexdigest()
  
  @classmethod
  def make(cls, dataset_key, fieldset_key, prop, value):
    """ Creates without saving """
    key_name = cls.get_key_name(fieldset_key, prop.name, value)
    return cls(key_name = key_name,
      dataset_key = dataset_key,
      fieldset_key = fieldset_key,
      property_name = prop.name,
      simplified_value = simplify(value),
      verbose_value = value,
      verbose_property = getattr(prop, 'verbose_name', prop.name),
      count=1)
  
  def update(self):
    """ Transactionally preserves count when doing a put """
    def _update():
      tag = db.get(self.key())
      if tag:
        self.count = (self.count or 0) + tag.count
      self.put()
    db.run_in_transaction(_update)  
  
  @property
  def name(self):
    return self.key().id_or_name()
